【分享】Android M新特性Doze and App Standby模式詳解 圖片

Optimizing for Doze and App Standby
1. 從Android6.0開始,Android提供了兩種省電延長電池壽命的功能:Doze和App Standby;
2. 表現(xiàn)形式:當(dāng)設(shè)備沒有連接到電源,設(shè)備進(jìn)入Doze模式時,系統(tǒng)將通過延遲最近用戶沒有使用的應(yīng)用程序的后臺CPU運作及網(wǎng)絡(luò)活動,讓應(yīng)用程序處于App Standby狀態(tài),以此來減少電池消耗。谷歌表示,在Nexus5和Nexus6上測試,當(dāng)屏幕處于關(guān)閉狀態(tài),平均續(xù)航時間提高30%;
3. 版本要求:Android6.0(API level 23)及其更高版本;
4. 開發(fā)者影響:為了保證用戶的最佳體驗,開發(fā)者有必要在Doze和App Standby模式下測試應(yīng)用程序,及其對代碼進(jìn)行相應(yīng)的調(diào)整。
Understanding Doze 解讀Doze
1.設(shè)備進(jìn)入Doze睡眠模式時機(jī):
用戶不操作設(shè)備一段時間
屏幕關(guān)閉
設(shè)備未連接電源充電
2.Doze模式下應(yīng)用程序有什么變化:
系統(tǒng)試圖通過限制應(yīng)用程序訪問網(wǎng)絡(luò)和CPU密集型服務(wù)節(jié)省電池;
防止應(yīng)用程序訪問網(wǎng)絡(luò),推延應(yīng)用程序的工作,同步,和標(biāo)準(zhǔn)的警報;
系統(tǒng)定期提供一個短暫的時間讓應(yīng)用程序完成延遲的工作活動,在這個時間片里,系統(tǒng)將提供維持性窗口應(yīng)用程序訪問網(wǎng)絡(luò),運行在等待的同步,工作,和報警等活動。
Doze模式的五種狀態(tài),分別如下:
ACTIVE:手機(jī)設(shè)備處于激活活動狀態(tài)
INACTIVE:屏幕關(guān)閉進(jìn)入非活動狀態(tài)
IDLE_PENDING:每隔30分鐘讓App進(jìn)入等待空閑預(yù)備狀態(tài)
IDLE:空閑狀態(tài)
IDLE_MAINTENANCE:處理掛起任務(wù)
如下圖所示,Doze期間提供間隔一小段時間(30s)供應(yīng)用程序使用網(wǎng)絡(luò)和處理掛起的活動。

從這張圖我們可以看到,系統(tǒng)進(jìn)入Doze模式后,系統(tǒng)會隔一段時間處理正在掛起的任務(wù),隨著時間推移,后面間隔的時間會越來越長,以此來減少電量消耗。
3.退出Doze模式(系統(tǒng)退出休眠,所有的應(yīng)用程序恢復(fù)正常活動):
用戶喚醒裝置移動,打開屏幕
或者設(shè)備連接電源
4.Doze有哪些限制?
網(wǎng)絡(luò)連接會被禁止
Wake Lock會被屏蔽
AlarmManager定時任務(wù)延遲到下一個maintenance window進(jìn)行處理,除非使用AlarmManager提供的方法:setAndAllowWhileIdle() 或者setExactAndAllowWhileIdle()
系統(tǒng)將不掃描熱點WIFI
同步工作將被禁止
不允許JobScheduler進(jìn)行任務(wù)調(diào)度
5.適配Doze模式有什么方法?
Doze影響到AlarmManager鬧鐘和定時器管理活動,在Android6.0引入了兩個新方法:setAndAllowWhileIdle() 和setExactAndAllowWhileIdle(),調(diào)用兩個方法可以在Doze模式下讓系統(tǒng)響應(yīng)定時任務(wù)
Doze模式下限制了網(wǎng)絡(luò)的連接,如果應(yīng)用程序依賴于實時信息,那么這個將影響App的體驗。那么你需要使用Google Cloud Messaging (GCM)谷歌云消息(后面詳細(xì)講解)
6.測試Doze和App Standby模式的方法(Adb命令)
測試Doze模式
1. 首先確保你的硬件或虛擬設(shè)備是Android6.0或更高版本系統(tǒng);
2. 連接設(shè)備到開發(fā)機(jī)上并安裝你的app;
3. 運行app并讓其運行活動;
4. 關(guān)閉設(shè)備的屏幕;
5. 運行以下adb命令使系統(tǒng)進(jìn)入Doze模式:
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
6. 觀察你的app表現(xiàn)行為是否有需優(yōu)化改進(jìn)的地方。
測試App Standby模式
步驟1-3同測試Doze模式
4. 運行以下adb命令迫使系統(tǒng)進(jìn)入App Standby模式:
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive <packageName> true
5. 模擬喚醒你的應(yīng)用程序使用以下命令:
$ adb shell am set-inactive <packageName> false
$ adb shell am get-inactive <packageName>
6. 觀察你的App,確保應(yīng)用程序恢復(fù)正常從待機(jī)模式過程中,App的通知及其背部活動能達(dá)到預(yù)期結(jié)果。
Understanding App Standby 解讀 App Standby
當(dāng)用戶不觸摸使用應(yīng)用程序一段時間時,該應(yīng)用程序處于App Standby狀態(tài),系統(tǒng)將把該App標(biāo)志為空閑狀態(tài)。除非觸發(fā)以下任意條件,應(yīng)用程序?qū)⑼顺鯝pp Standby狀態(tài):
1. 用戶主動啟動該App;
2. 該App當(dāng)前有一個前臺進(jìn)程(或包含一個活動的前臺服務(wù),或被另一個activity或前臺service使用);
3. App生成一個用戶所能在鎖屏或通知托盤看到的Notification, 而當(dāng)用戶設(shè)備插入電源時,系統(tǒng)將會釋放App的待機(jī)狀態(tài),允許他們自由的連接網(wǎng)絡(luò)及其執(zhí)行未完成的工作和同步。如果設(shè)備空閑很長一段時間,系統(tǒng)將允許空閑App一天一次訪問網(wǎng)絡(luò)。
Doze和App Standby的區(qū)別:
Doze模式需要屏幕關(guān)閉(通常晚上睡覺或長時間屏幕關(guān)閉才會進(jìn)入),而App Standby不需要屏幕關(guān)閉,App進(jìn)入后臺一段時間也會受到連接網(wǎng)絡(luò)等限制。
Using GCM to Interact with Your App While the Device is Idle
1. 什么是GCM?
Google Cloud Messaging(GCM)是一個云到設(shè)備的服務(wù),可以讓你支持實時在云端服務(wù)和Android設(shè)備上應(yīng)用程序之間的消息傳遞。
GCM提供了一個持久連接到云端的鏈接,讓所有需要實時消息傳遞應(yīng)用程序可以共享此鏈接。這個共享鏈接顯著優(yōu)化電池消耗,使其不必讓多個應(yīng)用程序各位維護(hù)自己單獨的持久鏈接而使電池迅速耗盡。
由于這個原因,官方建議:如果你的應(yīng)用需要消息傳遞與后端服務(wù)集成,我們強烈建議盡可能的使用GCM,而不是單獨維護(hù)自己的網(wǎng)絡(luò)鏈接。
GCM消息擁有高優(yōu)先級,不影響Doze模式,且不會不影響其他應(yīng)用程序的狀態(tài)。這意味著你的應(yīng)用程序可以使用它們進(jìn)行通信,同時最大限度地減少電池在整個系統(tǒng)和設(shè)備的影響。
以下來GCM自官方解釋:
一個GCM實現(xiàn)包括谷歌連接服務(wù)器,在你的環(huán)境中通過HTTP或XMPP協(xié)議的連接服務(wù)器進(jìn)行交互的應(yīng)用程序服務(wù)器和客戶端應(yīng)用程序。

生命周期流程:
注冊啟用GCM: 客戶端應(yīng)用程序注冊為接收消息。
發(fā)送和接收下行消息:
發(fā)送一個消息,該應(yīng)用程序服務(wù)器發(fā)送信息到客戶端應(yīng)用程序:
1.該應(yīng)用程序服務(wù)器發(fā)送消息給GCM連接服務(wù)器;
2.當(dāng)設(shè)備處于脫機(jī)狀態(tài),該GCM連接服務(wù)器入隊并存儲消息;
3.當(dāng)設(shè)備聯(lián)機(jī)時,GCM連接服務(wù)器將郵件發(fā)送到該設(shè)備;
4.在設(shè)備上,所述客戶端應(yīng)用程序根據(jù)該特定平臺實現(xiàn)接收該消息。
接收消息,客戶端應(yīng)用程序收到一條消息從GCM連接服務(wù)器。
發(fā)送和接收上游的消息: 如果您使用的是此功能只提供XMPP連接服務(wù)器 。
發(fā)送一個消息,客戶端應(yīng)用程序?qū)⑾l(fā)送到應(yīng)用服務(wù)器:
1.在設(shè)備上,客戶端應(yīng)用程序?qū)⑾l(fā)送到XMPP連接server;
2.如果該服務(wù)器已斷開連接,該XMPP服務(wù)器連接入隊并存儲信息;
3.當(dāng)應(yīng)用程序服務(wù)器重新連接后,XMPP連接服務(wù)器將郵件發(fā)送到應(yīng)用程序服務(wù)器。
接收消息,一個應(yīng)用服務(wù)器從XMPP連接服務(wù)器接收郵件,然后執(zhí)行以下操作:
1、解析消息頭,以驗證客戶端應(yīng)用程序發(fā)送的信息;
2、發(fā)送“確認(rèn)”的XMPP連接服務(wù)器以確認(rèn)收到該消息;
3、任選解析該消息有效載荷,由客戶端應(yīng)用程序所定義的。
除了GCM,Android6.0及更高版本還提供了Doze模式白名單列表,通過設(shè)置應(yīng)用程序進(jìn)入白名單列表可逃脫Doze模式的各種限制。
檢測應(yīng)用程序是否存在白名單list里面,可使用PowerManager的isIgnoringBatteryOptimizations()方法。
用戶也可手動設(shè)置應(yīng)用程序進(jìn)入白名單列表里面,路徑為:設(shè)置>電池>電池優(yōu)化白名單:


客戶端使用方法:
1. App程序可發(fā)送action為ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS的intent引導(dǎo)用戶進(jìn)入設(shè)置界面將應(yīng)用程序設(shè)置進(jìn)白名單列表里。
2. 應(yīng)用程序還可以使用AREQUEST_IGNORE_BATTERY_OPTIMIZATI* 權(quán)限來觸發(fā)一個系統(tǒng)對話來讓用戶添加到白名單里,而無需進(jìn)入設(shè)置界面去設(shè)置。
當(dāng)然,官方也提供用戶把你的App移除電池優(yōu)化白名單的選項。這個白名單也會被Android M的另一個新特性 App Standby使用,所以用戶只能簡單的進(jìn)行控制,也就是說設(shè)備并不會完全相信這個白名單。
官方舉了一下白名單例子:

$ adb shell dumpsys deviceidle whitelist +<packageName>
$ adb shell dumpsys deviceidle

總結(jié):



